package com.ai.opc;

import com.ai.entity.made.OpcNodeInfo;
import com.ai.entity.made.OpcServerInfo;
import com.ai.service.made.IOpcNodeInfoService;
import com.ai.service.made.IOpcServerInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.concurrent.*;

/**
 * @Author jiaok
 * @Date 2024-11-14 11:12
 */
@Slf4j
public class OpcThreadPoolExecutor {

    private static final int CORE_POOL_SIZE = 5;
    private static final int MAX_POOL_SIZE = 10;
    private static final int QUEUE_CAPACITY = 100;
    private static final Long KEEP_ALIVE_TIME = 1L;


   public static ThreadPoolExecutor executorService = new ThreadPoolExecutor(
            CORE_POOL_SIZE,
            MAX_POOL_SIZE,
            KEEP_ALIVE_TIME,
            TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(QUEUE_CAPACITY),
            new ThreadPoolExecutor.CallerRunsPolicy());


    /**
     * 新增opc server 信息时，建立对应的连接
     * @param opcServerInfo opc-server 信息
     * @param iOpcServerInfoService service
     */
    public static void  startConnectOpcServerTask(OpcServerInfo opcServerInfo, IOpcServerInfoService iOpcServerInfoService){

        log.info("===========================  准备开始连接 opc Server  ===========================");
        executorService.submit(new OpcServerRunnable(opcServerInfo, iOpcServerInfoService));
        log.info("===========================  连接   opc Server  结束 ===========================");
    }

    /**
     * 项目初始化时，建立opc Server连接，并监听各个server下的节点值
     * @param opcServerInfo opc server 信息
     * @param iOpcServerInfoService service
     * @param opcNodeInfoList 该server下的所有节点
     */
    public static void initOpcConnectSubNode(OpcServerInfo opcServerInfo, IOpcServerInfoService iOpcServerInfoService, List<OpcNodeInfo> opcNodeInfoList, IOpcNodeInfoService iOpcNodeInfoService){

        log.info("===========================  +++++++++++++++连接opc：{}  开始 ===========================",opcServerInfo.getOpcServerName());
        Future<?> opcServerFuture = executorService.submit(new OpcServerRunnable(opcServerInfo, iOpcServerInfoService));

        try {
            opcServerFuture.get();
        }catch (InterruptedException | ExecutionException e) {
            log.error("===========================   OpcServerRunnable 任务执行失败   ===========================", e);
            Thread.currentThread().interrupt();
            //opcServer未建立连接，则直接返回不执行后续的方法
            return;
        }

        if (!CollectionUtils.isEmpty(opcNodeInfoList)){
            for (OpcNodeInfo opcNodeInfo : opcNodeInfoList) {
                executorService.submit(new OpcNodeRunnable(opcNodeInfo,iOpcServerInfoService,iOpcNodeInfoService));
            }
        log.info("===========================  +++++++++++++++连接opc：{}  结束 ===========================",opcServerInfo.getOpcServerName());
        }
    }

    /**
     * 停止线程池
     */
    public void shutdown() {
        executorService.shutdown();
    }

}
